package net.ebakker.tvseries.main;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import net.ebakker.sheets.SheetDownloader;
import net.ebakker.subtitles.SubtitleDownloader;
import net.ebakker.tvseries.archive.ArchiveExtracter;
import net.ebakker.tvseries.reader.JsonReader;

import org.json.simple.parser.ParseException;

import com.googlecode.opensubtitlesjapi.LANGUAGE;
import com.googlecode.opensubtitlesjapi.OpenSubtitlesException;

public class Main {
	private static String SHEET_TEMPLATE = "/opt/sheetmaker/episodeconf.conf";

	private static Map<String, Pair<String, File>> seriesMap;
	private static File listOldTorrents;
	private static String subtitlePassword;
	private static String subtitleUsername;

	private static File missingSubtitleFile;

	public static void main(String[] args) throws ParseException {
		subtitleUsername = args[3];
		subtitlePassword = args[4];
		listOldTorrents = new File(args[0]);
		missingSubtitleFile = new File(args[5]);
		try {
			List<File> torrents = getTorrents(args[1]);
			seriesMap = JsonReader.readFile(new File(args[2]));
			ArchiveExtracter extracter = extractTorrents(torrents);
			List<File> resultingFiles = updateList(extracter);
			SheetDownloader.createSheets(resultingFiles, SHEET_TEMPLATE);
			downloadSubtitles(resultingFiles);
			Set<File> extractedArchives = extracter.getExtractedArchives();
			updateOldFile(listOldTorrents, extractedArchives, false, true);
		} catch (IOException | OpenSubtitlesException e) {
			e.printStackTrace();
		}
	}

	private static List<File> updateList(ArchiveExtracter extracter) throws IOException {
		updateOldFile(listOldTorrents, extracter.getExtractedArchives(), false, true);
		return extracter.getExtractedFiles();
	}

	private static ArchiveExtracter extractTorrents(List<File> torrents) {
		ArchiveExtracter extracter = new ArchiveExtracter(seriesMap);
		extracter.extractFiles(torrents);
		return extracter;
	}

	private static List<File> getTorrents(String torrentsDir) throws IOException {
		List<File> readOldFile = readOldFile(listOldTorrents, torrentsDir);
		File torrentDir = new File(torrentsDir);
		List<File> torrents = new ArrayList<>(Arrays.asList(torrentDir.listFiles()));
		compareLists(readOldFile, torrents);
		return torrents;
	}

	private static void downloadSubtitles(List<File> resultingFiles) throws OpenSubtitlesException,
			IOException {
		updateOldFile(missingSubtitleFile, resultingFiles, true, true);
		List<File> allFiles = readOldFile(missingSubtitleFile, "");
		allFiles.addAll(resultingFiles);
		List<File> downloadedSubs = new ArrayList<>();
		SUBS: for (File file : allFiles) {
			System.out.println("Starting subtitle search for: " + file.getName());
			Map<LANGUAGE, Boolean> subtitles =
					SubtitleDownloader.downloadSubtitles(file, subtitleUsername, subtitlePassword,
							Arrays.asList(LANGUAGE.DUT, LANGUAGE.ENG));
			for (Entry<LANGUAGE, Boolean> subtitle : subtitles.entrySet()) {
				if (subtitle.getValue().booleanValue()) {
					downloadedSubs.add(file);
					continue SUBS;
				}
			}

		}
		allFiles.removeAll(downloadedSubs);
		updateOldFile(missingSubtitleFile, allFiles, true, false);
		SubtitleDownloader.logOut();
	}

	private static void updateOldFile(File oldFile, Collection<File> newFiles, boolean fullPath,
			boolean append) throws IOException {
		PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(oldFile, append)));
		try {
			for (File file : newFiles) {
				out.println(fullPath ? file.getAbsolutePath() : file.getName());
			}
		} finally {
			out.close();
		}
	}

	private static void compareLists(List<File> readOldFile, List<File> torrents) {
		for (File torrent : readOldFile) {
			torrents.remove(torrent);
		}

	}

	private static List<File> readOldFile(File oldTorrentsFile, String torrentsDir)
			throws IOException {
		String line;
		List<File> oldTorrents = new ArrayList<>();
		FileInputStream fis = new FileInputStream(oldTorrentsFile);
		BufferedReader reader =
				new BufferedReader(new InputStreamReader(fis, Charset.forName("UTF-8")));
		try {
			while ((line = reader.readLine()) != null) {
				oldTorrents.add(new File(torrentsDir, line));
			}
			return oldTorrents;
		} finally {
			reader.close();
		}
	}
}
